/**
 * D5Power Studio FPower 2D MMORPG Engine
 * 第五动力FPower 2D 多人在线角色扮演类网页游戏引擎
 * 
 * copyright [c] 2010 by D5Power.com Allrights Reserved.
 */ 
package com.D5Power.scene
{
	import com.D5Power.Controler.BaseLuaControler;
	import com.D5Power.Controler.CharacterControler;
	import com.D5Power.Controler.ControllerCenter;
	import com.D5Power.Controler.NCharacterControler;
	import com.D5Power.GMath.data.qTree.QTree;
	import com.D5Power.Lua.LuaDispatch;
	import com.D5Power.Objects.CharacterObject;
	import com.D5Power.Objects.Effects.NoticeEffect;
	import com.D5Power.Objects.GameObject;
	import com.D5Power.map.WorldMap;
	
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.BlendMode;
	import flash.display.Stage;
	import flash.geom.ColorTransform;
	import flash.geom.Matrix;
	import flash.geom.Rectangle;
	import flash.utils.getTimer;
	
	import luaAlchemy.LuaAlchemy;
	


	public class BaseScene implements LuaDispatch
	{
		/**
		 * 游戏内的现实对象
		 */
		protected var objects:Array;
		/**
		 * 地图
		 */ 
		protected var map:WorldMap;
		
		/**
		 * Lua 脚本执行器
		 */ 
		protected var myLua:LuaAlchemy;
		
		/**
		 * Lua 脚本控制器
		 */ 
		protected var _lua_controler:BaseLuaControler;

		/**
		 * 渲染列表
		 */ 
		protected var _renderList:Array;
		
		/**
		 * 双缓冲区
		 */ 
		public var doubleBuffer:BitmapData;
		
		/**
		 * 游戏对象四叉树
		 */ 
		protected var qTree:QTree;
		
		/**
		 * 效果缓冲区，本缓冲区位于最上层
		 */ 
		public var effectBuffer:BitmapData;
		
		public var effectLayer:Bitmap = new Bitmap(effectBuffer);
		
		/**
		 * 公告器数组
		 */ 
		protected var notice_list:Array = new Array();
		
		/**
		 * 公告器显示开始位置
		 */ 
		protected var notice_start:uint = 100;
		
		
		protected var _stage:Stage;
		
		protected var _isReady:Boolean=false;
		
		/**
		 * 主角
		 */ 
		protected var player:CharacterObject;
		
		/**
		 * 控制器中心
		 */ 
		protected var _ctrlCenter:ControllerCenter;
		
		
		public function BaseScene(stg:Stage)
		{
			_stage=stg;
			effectLayer.blendMode = BlendMode.ADD;

			objects = new Array();
			buildBuffer();
			
			// 定义控制器中心
			_ctrlCenter = new ControllerCenter();
		}
		
		public function buildQtree():void
		{
			qTree = new QTree(new Rectangle(0,0,Global.MAPSIZE.x,Global.MAPSIZE.y),4);
			_renderList = new Array();
		}
		
		/**
		 * 控制中心
		 */ 
		public function get ctrlCenter():ControllerCenter
		{
			return _ctrlCenter;
		}
		
		/**
		 * 渲染列表（只有在四叉树渲染优化的前提下才不为NULL）
		 */ 
		public function get renderList():Array
		{
			return _renderList;
		}
		
		public function get Player():CharacterObject
		{
			return player;
		}
		/**
		 * 设置用户控制器
		 * @param	ctrl 用户控制器
		 */ 
		protected function setPlayerCtrl(ctrl:CharacterControler):void
		{
			_ctrlCenter.PlayerController = ctrl;
		}
		
		/**
		 * 添加NPC控制器
		 * @param	ctrl	NPC控制器
		 * @param	uid		用户ID
		 */ 
		protected function addNCtrl(ctrl:NCharacterControler,key:*):void
		{
			_ctrlCenter.addNController(ctrl,key);
		}
		
		/**
		 * 初始化缓冲区
		 */ 
		public function buildBuffer():void
		{
			doubleBuffer = new BitmapData(Global.W,Global.H,false,0);
			effectBuffer = new BitmapData(Global.W,Global.H,false,0);
		}
		
		/**
		 * 镜头注视
		 */ 
		public function focus(o:GameObject=null):void
		{
			if(o==null)
			{
				if(player==null)
				{
					Global.msg("Can not fllow null object.");
					return;
				}else{
					map.fllow(player);
				}
			}else{
				map.fllow(o);
			}
		}
		
		/**
		 * 确认某指定目标是否在当前的镜头视野中
		 */ 
		public function inScene(obj:GameObject):Boolean
		{
			if(qTree==null) return true;
			return qTree.isIn(obj.Pos.x,obj.Pos.y);
		}
		
		/**
		 * 初始化地图
		 */ 
		protected function setMap():void
		{
			map = new WorldMap();
		}
		
		/**
		 * 向场景中添加游戏对象
		 */ 
		public function addObject(o:GameObject):void
		{
			if(objects.indexOf(o)!=-1) return;
			objects.push(o);
			if(qTree!=null)
			{
				o.qTree = qTree.add(o,o.Pos.x,o.Pos.y);
			}
		}
		
		/**
		 * 获得特定的游戏对象
		 * @param	i	索引
		 */ 
		public function getObject(i:uint):GameObject
		{
			if(i>ObjectsNumber)
				return null;
			else
				return objects[i] as GameObject;	
		}
		
		/**
		 * 获得特定的角色对象
		 * 
		 * @param	i	索引
		 */ 
		public function getCharacter(i:uint):CharacterObject
		{
			if(i>ObjectsNumber)
				return null;
			else
				return objects[i] as CharacterObject;
		}
		
		/**
		 * 得到所有游戏对象
		 */
		public function getAllObjects():Array
		{
			return objects;
		}
		
		/**
		 * 获得目前舞台中的
		 * 
		 */ 
		public function get ObjectsNumber():uint
		{
			return objects.length;
		}
		
		public function removeObject(o:GameObject):void
		{
			var i:int = objects.indexOf(o);
			
			if(i!=-1) objects.splice(i,1);
			
			if(qTree!=null)
			{
				qTree.remove(o);
			}
			
			o.clear();
			o=null;
		}
		
		/**
		 * 记忆工作区
		 */ 
		public function set stage(s:Stage):void
		{
			_stage=s;
		}
		
		/**
		 * 获取工作区
		 */ 
		public function get stage():Stage
		{
			return _stage;
		}
		
		/**
		 * 当前场景的地图
		 */ 
		public function get Map():WorldMap
		{
			return map;
		}
		/**
		 * 是否加载完成
		 */ 
		public function get isReady():Boolean
		{
			return _isReady;
		}
		/**
		 * 渲染输出
		 * 
		 */ 
		public function render():void
		{
			updateTime();
			
			effectBuffer.fillRect(effectBuffer.rect,0x000000);
			
			draw();
			
			//doubleBuffer.draw(effectBuffer,new Matrix(),new ColorTransform(),BlendMode.ADD);
		}
		
		protected function updateTime():void
		{
			Global.Timer = getTimer();
		}
		
		protected function draw():void
		{
			if(WorldMap.needUpdate) map.render(doubleBuffer);
			
			var item:GameObject
			if(qTree!=null)
			{
				_renderList = qTree.getDataInRect(Map.cameraCutView);
				_renderList.sortOn("zOrder",Array.NUMERIC);
				
				
				for each(item in _renderList)
				{
					item.clearMe();
				}
				
				for each(item in _renderList)
				{
					item.renderMe();
				}
			}else{
				objects.sortOn("zOrder",Array.NUMERIC);
				
				for each(item in objects)
				{
					item.clearMe();
				}
				
				for each(item in objects)
				{
					item.renderMe();
				}
			}
		}
		
		/**
		 * 运行Lua脚本
		 * @param	src	脚本内容
		 */
		public function runLua(src:String):void
		{
			myLua = new LuaAlchemy();
			myLua.setGlobal('me',this);
			myLua.setGlobal('Global',Global);
			var result:Array = myLua.doString(src);
		}
		
		/**
		 * 读取Lua脚本
		 * @param	url	脚本的URL
		 */ 
		public function setLua(url:String):void
		{
			if(_lua_controler==null) _lua_controler = new BaseLuaControler(this);
			_lua_controler.scriptURL = Global.LUAPATH+'scene/'+url;
		}
		
		public function clear():void
		{
			doubleBuffer.dispose();
		}
	}
}